#ifndef _EVENTLOOP_
#define _EVENTLOOP_

#include "noncopyable.h"
#include "Timestamp.h"
#include "CurrentThread.h"

#include <vector>
#include <functional>
#include <memory>
#include <mutex>
#include <atomic>

class Channel;
class Poller;

class EventLoop : noncopyable{
public:
    using Functor = std::function<void()>;
    EventLoop();
    ~EventLoop();

    void loop();                                //開啓事件循環
    void quit();                                //推出事件循環
    inline Timestamp pollRecturnTime() const { return pollReturnTime_; }
    void runInLoop(Functor cb);                 //在當前loop中執行回調
    void queueInLoop(Functor cb);               //把回調放入隊列中，喚醒loop所在線程，執行回調
    void wakeup();                              //喚醒loop所在線程
    
    //EventLoop的方法 >>> 調用Poller的方法
    void updateChannel(Channel *channel);       
    void removeChannel(Channel *channel);
    bool hasChannel(Channel *channel);

    //判斷EventLoop對象是否在自己的線程
    inline bool isInLoopThread() const { return threadId_ == CurrentThread::tid(); }

private:
    void handleRead();                          //處理wakeup
    void doPendingFunctors();                   //執行回調

    using ChannelList = std::vector<Channel*>;
    std::atomic_bool looping_;                  //原子操作，通過CAS實現
    std::atomic_bool quit_;                     //標誌退出loop循環
    const pid_t threadId_;                      //記錄當前loop在線程的id
    Timestamp pollReturnTime_;                  //poller返回發生事件的channel的時間點
    std::unique_ptr<Poller> poller_;

    int wakeupFd_;                              //當mainLoop獲取一個新用戶的channel，通過論尋算法選擇一個subLoop，通過該成員喚醒subLoop處理channel
    std::unique_ptr<Channel> wakeupChannel_;    

    ChannelList activeChannels_;
    Channel* currentActiveChannel_;
    std::atomic_bool callingPendingFunctors_;   //標識當前loop是否有需要執行的回調函數
    std::vector<Functor> pendingFunctors_;      //存儲loop需要執行的回調函數
    std::mutex mutex_;                          //互斥鎖，保護上面vector容器的線程安全操作
};

#endif